#pragma once
#include <Rz/Object.h>
#include <Rz/Graphics/Render/ITexture2D.h>
#include "API/GLDefinitions.h"

namespace Rz { namespace Graphics { namespace Render { namespace Libraries { namespace OpenGL {

class GLTexture2D :
	public Object,
	virtual public ITexture2D
{
	public:
		RZ_RTTI(Rz::Graphics::Render::Libraries::OpenGL, GLTexture2D);
		RZ_RTTI_IMPLEMENTS(Object, ITexture2D);
		RZ_RTTI_END;

		using ITexture2D::GetData;
		using ITexture2D::SetData;

		GLTexture2D(IRenderDevice* renderDevice);
		GLTexture2D(IRenderDevice* renderDevice, u32 width, u32 height);
		GLTexture2D(IRenderDevice* renderDevice, u32 width, u32 height, bool mipMap, SurfaceFormat surfaceFormat);
		virtual ~GLTexture2D();

		virtual void Bind() override;
		virtual void Unbind() override;

		void Init(SurfaceFormat surfaceFormat, u32 width, u32 height, const void* data);

		virtual void SetData(const void* data, u32 dataLength, u32 startIndex, u32 offsetInBytes) override;
		virtual void GetData(void* data, u32 count, u32 startIndex) const override;

		GLuint GetTextureHandle() const;

	private:
		static void SurfaceToPixelFormat(SurfaceFormat surfaceFormat, GLenum* internalFormat, GLenum* format, GLenum* type);

		GLuint _handle;
		u32	_width;
		u32 _height;
		bool _mipMap;
		SurfaceFormat _surfaceFormat;

		GLenum _glInternalFormat;
		GLenum _glFormat;
		GLenum _glType;
};

} } } } }
